#include "jwaitbar.h"
#include <QTimerEvent>
#include <QPaintEvent>
#include <QResizeEvent>
#include <QPainterPath>
#include <QPainter>

namespace QTE
{

class Q_DECL_HIDDEN JWaitBarPrivate : public QObject
{
public:
	JWaitBarPrivate(JWaitBar &wb);
	~JWaitBarPrivate() override;

public:
	void start(int m_msecs);
	void stop();

private:
	void timerEvent(QTimerEvent *event) override;

public:
	JWaitBar *q_ptr;
	int m_timerID = -1;
	int m_msecs = -1;
	int m_blockWidth;
	QRect m_rect;
};

JWaitBarPrivate::JWaitBarPrivate(JWaitBar &wb) :
	q_ptr(&wb)
{

}

JWaitBarPrivate::~JWaitBarPrivate()
{
	stop();
}

void JWaitBarPrivate::start(int msecs)
{
	if( m_timerID == -1 )
	{
		m_timerID = startTimer(msecs);
		this->m_msecs = msecs;
		q_ptr->update();
	}
	else if( this->m_msecs != msecs )
	{
		killTimer(m_timerID);
		this->m_msecs = msecs;
		m_timerID = startTimer(msecs);
	}
}

void JWaitBarPrivate::stop()
{
	if( m_timerID != -1 )
	{
		killTimer(m_timerID);
		m_timerID = m_msecs = -1;
		m_rect.setX(0);
		m_rect.setWidth(m_blockWidth);
	}
}

void JWaitBarPrivate::timerEvent(QTimerEvent *event)
{
	if( event->timerId() == m_timerID )
		q_ptr->update();
}

/*---------------------------------------------------------------------------*/

JWaitBar::JWaitBar(QWidget *parent) :
	QWidget(parent),
	d_ptr(new JWaitBarPrivate(*this))
{
#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
	setAttribute(Qt::WA_PaintOutsidePaintEvent);
#endif //QT_VERSION

	d_ptr->m_blockWidth = width() / 5;
	d_ptr->m_rect.setRect(1-d_ptr->m_blockWidth, 1, d_ptr->m_blockWidth, 0);
}

JWaitBar::~JWaitBar()
{
	delete d_ptr;
}

void JWaitBar::start(int msecs)
{
	if( msecs <= 0 )
		msecs = 200;
	d_ptr->start(msecs);
}

void JWaitBar::stop()
{
	d_ptr->stop();
}

void JWaitBar::paintEvent(QPaintEvent *event)
{
	QWidget::paintEvent(event);

	QPainter painter(this);
	painter.setPen(Qt::black);

	QRect rect(0, 0, width()-1, height()-1);
	painter.drawRect(rect);

	QPainterPath path;
	rect.setRect(1, 1, width()-2, height()-2);
	path.addRect(rect);
	painter.fillPath(path, QBrush(Qt::white));

	if( d_ptr->m_timerID != -1 )
	{
		QPainterPath path;
		d_ptr->m_rect.setRect(d_ptr->m_rect.x()+d_ptr->m_blockWidth, 1,
							d_ptr->m_blockWidth, height()-2);
		if( d_ptr->m_rect.right() > width() - 1 )
		{
			d_ptr->m_rect.setWidth(width()-d_ptr->m_rect.x()-1);
			int cutting = d_ptr->m_blockWidth - d_ptr->m_rect.width();
			path.addRect(1, 1, cutting, height()-2);
			path.addRect(d_ptr->m_rect);
			painter.fillPath(path, QBrush(QColor(100,200,100)));
			d_ptr->m_rect.setRect(cutting-d_ptr->m_blockWidth, 1,
								d_ptr->m_blockWidth, height()-2);
			return ;
		}

		path.addRect(d_ptr->m_rect);
		painter.fillPath(path, QBrush(QColor(100,200,100)));
	}
}

void JWaitBar::resizeEvent(QResizeEvent *event)
{
	d_ptr->m_blockWidth = event->size().width() / 5;
	d_ptr->m_rect.setRect(1-d_ptr->m_blockWidth, 1, d_ptr->m_blockWidth, 0);
	QWidget::resizeEvent(event);
}

void JWaitBar::showEvent(QShowEvent *event)
{
	if( d_ptr->m_msecs > 0 and d_ptr->m_timerID == -1 )
		d_ptr->m_timerID = d_ptr->startTimer(d_ptr->m_msecs);
	return QWidget::showEvent(event);
}

void JWaitBar::hideEvent(QHideEvent *event)
{
	d_ptr->killTimer(d_ptr->m_timerID);
	d_ptr->m_timerID = -1;
//	d_ptr->rect.setRect(1-d_ptr->block_width, 1, d_ptr->block_width, 0);
	return QWidget::hideEvent(event);
}

} //namespace QTE
